<?php

declare(strict_types=1);

/**
 * This file is part of Hyperf.
 *
 * @link     https://www.hyperf.io
 * @document https://doc.hyperf.io
 * @contact  group@hyperf.io
 * @license  https://github.com/hyperf/hyperf/blob/master/LICENSE
 */

use Hyperf\Amqp\Message\ProducerMessageInterface;
use Hyperf\Amqp\Producer;
use Hyperf\AsyncQueue\Driver\DriverFactory;
use Hyperf\AsyncQueue\JobInterface;
use Hyperf\ExceptionHandler\Formatter\FormatterInterface;
use Hyperf\Utils\ApplicationContext;
use Psr\Container\ContainerInterface;

if (!function_exists('di')) {
    /**
     * Finds an entry of the container by its identifier and returns it.
     * @param null|mixed $id
     * @return mixed|ContainerInterface
     */
    function di($id = null)
    {
        $container = ApplicationContext::getContainer();
        if ($id) {
            return $container->get($id);
        }

        return $container;
    }
}

if (!function_exists('format_throwable')) {
    /**
     * Format a throwable to string.
     * @param Throwable $throwable
     * @return string
     */
    function format_throwable(Throwable $throwable): string
    {
        return di()->get(FormatterInterface::class)->format($throwable);
    }
}

if (!function_exists('queue_push')) {
    /**
     * Push a job to async queue.
     * @param JobInterface $job
     * @param int $delay
     * @param string $key
     * @return bool
     */
    function queue_push(JobInterface $job, int $delay = 0, string $key = 'default'): bool
    {
        $driver = di()->get(DriverFactory::class)->get($key);
        return $driver->push($job, $delay);
    }
}

if (!function_exists('amqp_produce')) {
    /**
     * Produce a amqp message.
     * @param ProducerMessageInterface $message
     * @return bool
     */
    function amqp_produce(ProducerMessageInterface $message): bool
    {
        return di()->get(Producer::class)->produce($message, true);
    }
}


if (!function_exists('tree_to_list')) {
    function tree_to_list(array $tree, $pid = 0)
    {
        $list = [];
        foreach ($tree as $node) {
            $list[$node['id']] = [
                'id' => $node['id'],
                'pid' => $pid,
                'name' => $node['name'],
                'title' => $node['title'],
                'type' => $node['type'],
                'path' => isset($node['path']) ? $node['path'] : '',
                'api' => isset($node['api']) ? $node['api'] : ''
            ];
            if (isset($node['children'])) {
                $subList = tree_to_list($node['children'], $node['id']);
                foreach ($subList as $subNode) {
                    $list[$subNode['id']] = $subNode;
                }
            }
        }
        return $list;
    }
}

if (!function_exists('dump')) {
    function dump($content)
    {
        print_r("\n--------------------------\n");
        var_dump($content);
        print_r("\n--------------------------\n");
    }
}

if (!function_exists('vdump')) {
    /**
     * Dump data like var_dump
     *
     * @param mixed ...$vars
     */
    function vdump(...$vars)
    {
        $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);

        $line = $trace[0]['line'];
        $pos  = $trace[1]['class'] ?? $trace[0]['file'];

        if ($pos) {
            echo "PRINT ON $pos($line):\n";
        }

        ob_start();
        /** @noinspection ForgottenDebugOutputInspection */
        var_dump(...$vars);

        $string = ob_get_clean();

        echo preg_replace(["/Array[\s]*\(/", "/=>[\s]+/i"], ['Array (', '=> '], $string);
    }
}